package xp2p.adv.jxta;

import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Enumeration;
import net.jxta.document.Advertisement;
import net.jxta.document.AdvertisementFactory;
import net.jxta.document.Element;
import net.jxta.document.MimeMediaType;
import net.jxta.document.StructuredDocument;
import net.jxta.document.TextElement;
import net.jxta.id.ID;
import net.jxta.id.IDFactory;
import net.jxta.peergroup.PeerGroupID;

public class AppAdv extends AdvBase
{
	public static class Instantiator implements
			AdvertisementFactory.Instantiator
	{

		public String getAdvertisementType()
		{
			return AppAdv.AdvDocTypeString;
		}

		public Advertisement newInstance()
		{
			return new AppAdv();
		}

		public Advertisement newInstance(Element root)
		{
			return new AppAdv(root);
		}
	}

	public static String AdvDocTypeString = "jxta:xp2pAppAdv";
	public final static String ArgumentsTag = "args";
	public final static String ClassTag = "class";
	public final static String FileNameTag = "fname";
	public final static String FilesTag = "files";
	public final static String JarsTag = "jars";
	public final static String NameTag = "name";
	public final static String PNumRealTag = "pnumreal";

	public final static String PNumTag = "pnum";

	public static void RegisterSelf()
	{
		AdvertisementFactory.registerAdvertisementInstance(AdvDocTypeString,
				new Instantiator());
	}

	public AppAdv()
	{
		super();
	}

	public AppAdv(Element root)
	{
		super(root);
	}

	@Override
	public AppAdv clone() throws CloneNotSupportedException
	{
		return new AppAdv(this.getStructuredDocument(MimeMediaType.XMLUTF8)
				.getRoot());
	}

	@SuppressWarnings({ "rawtypes", "unchecked" })
	@Override
	protected Element createElement(StructuredDocument target, String key,
			Object value)
	{
		if (key == FilesTag)
		{
			Element result = target.createElement(FilesTag);
			target.appendChild(result);
			ArrayList<String> files = (ArrayList<String>) Properties.get(key);
			for (String f : files)
			{
				Element elem = super.createElement(target, result, FileNameTag,
						f);
			}
			return result;
		}
		if (key == JarsTag)
		{
			Element result = target.createElement(JarsTag);
			target.appendChild(result);
			ArrayList<String> files = (ArrayList<String>) Properties.get(key);
			for (String f : files)
			{
				Element elem = super.createElement(target, result, FileNameTag,
						f);
			}
			return result;
		}
		return super.createElement(target, key, value);
	}

	@Override
	protected void DefineProps()
	{
		super.DefineProps();
		Properties.put(JarsTag, new ArrayList<String>());
		Properties.put(FilesTag, new ArrayList<String>());
		Properties.put(FileNameTag, null);
		Properties.put(IdTag, null);
		Properties.put(ClassTag, null);
		Properties.put(NameTag, null);
		Properties.put(PNumRealTag, null);
		Properties.put(PNumTag, null);
		Properties.put(ArgumentsTag, null);
	}

	public String getClassName()
	{
		return (String) Properties.get(ClassTag);
	}

	@Override
	public String getDocType()
	{
		return AdvDocTypeString;
	}

	public PeerGroupID getPeerGroupID()
	{
		return PeerGroupID.create(URI.create((String) Properties.get(IdTag)));
	}

	public String getName()
	{
		return (String) Properties.get(NameTag);
	}

	@Override
	protected void ProcessElement(TextElement element)
	{
		String name = element.getName();
		if (name.compareTo(FilesTag) == 0)
		{
			Properties.put(FilesTag, ProcessFileNames(element));
			return;
		}
		if (name.compareTo(JarsTag) == 0)
		{
			Properties.put(JarsTag, ProcessFileNames(element));
			return;
		}
		super.ProcessElement(element);
	}

	private ArrayList<String> ProcessFileNames(TextElement theElement)
	{
		Enumeration TheElements = theElement.getChildren();
		ArrayList<String> files = new ArrayList<String>();
		while (TheElements.hasMoreElements())
		{
			TextElement TheElement = (TextElement) TheElements.nextElement();
			if (TheElement.getName().compareTo(FileNameTag) == 0)
			{
				files.add(TheElement.getValue());
			}
		}
		return files;
	}

	public void setClassName(String name)
	{
		Properties.put(ClassTag, name);
	}

	public void setPeerGroupID(PeerGroupID id)
	{
		Properties.put(IdTag, id.toURI().toString());
	}

	public void setName(String name)
	{
		Properties.put(NameTag, name);
	}
}
